package main

import (
	"bytes"
	"fmt"
	"os"
	"unicode"
	"strings"
)

func main()  {
	//bytesMain()
	//bytesBufferMain()
	bytesReaderMain()
}

func bytesMain()  {
	a := []byte("aaaabbbbccc")
	b := []byte("ab")
	fmt.Println(a,b)

	// 比较 a 和 b 是否相等，长度及字节都相同
	bytesEqual := bytes.Equal(a,b)
	fmt.Println(bytesEqual)

	// 判断a与b是否相同，忽略大小写
	bytesEqualFold := bytes.EqualFold(a, b)
	fmt.Println(bytesEqualFold)

	// 比较 a 和 b，a等于b 结果为0，a小于b 结果为1，a大于b 结果为-1
	bytesCompare := bytes.Compare(a,b)
	fmt.Println(bytesCompare)

	// 计数 s 中，sep 的非重叠数量
	// 若sep为空切片，则返回1+s
	bytesCount := bytes.Count(a,b)
	fmt.Println(bytesCount)

	// b中是否包含subslice
	bytesContains := bytes.Contains(a,b)
	fmt.Println(bytesContains)

	// b中是否至少包含chars任意一个字符，若是则返回true，否则返回false
	bytesContainsAny := bytes.ContainsAny(a,"aaaadddd")
	fmt.Println(bytesContainsAny)

	// b中是否包含r字符，
	bytesContainRune := bytes.ContainsRune(a,'c')
	fmt.Println(bytesContainRune)

	// 检索a中首个b的位置，未检索到返回-1
	bytesIndex := bytes.Index(a, b)
	fmt.Println(bytesIndex)

	// 检索b中首个c的位置,检索不到返回-1
	bytesIndexByte := bytes.IndexByte(a,'d')
	fmt.Println(bytesIndexByte)

	// 返回s中第一次出现r字节的索引
	bytesIndexRune := bytes.IndexRune(a,'c')
	fmt.Println(bytesIndexRune)

	// s中第一次出现 chars中任意一个字符 的索引
	bytesIndexAny := bytes.IndexAny(a,"bca")
	fmt.Println(bytesIndexAny)

	// 返回s中最后一个sep索引，若检索不到，返回-1
	bytesLastIndex := bytes.LastIndex(a,b)
	fmt.Println(bytesLastIndex)

	// 返回s中最后一个字符c的索引
	bytesLastIndexByte := bytes.LastIndexByte(a,'c')
	fmt.Println(bytesLastIndexByte)

	// s中最后一次出现 chars中任意字符 的索引
	bytesLastindexAny := bytes.LastIndexAny(a,"bca")
	fmt.Println(bytesLastindexAny)

	// 将 s 以指定的字符 sep 进行分割
	bytesSplit := bytes.Split(a,b)
	fmt.Println(bytesSplit)

	// 将 s 以指定的字符 sep 进行分割，n为分割个数，-1分割所有
	bytesSplitN := bytes.SplitN(a,b,-1)
	fmt.Println(bytesSplitN)

	// 将 s 以指定的字符 sep 进行分割，保留sep
	bytesSplitAfter := bytes.SplitAfter(a,b)
	fmt.Println(bytesSplitAfter)

	// 将 s 以指定的字符 sep 进行分割，保留sep,n为分割个数，-1分割所有
	bytesSplitAfterN := bytes.SplitAfterN(a,b,-1)
	fmt.Println(bytesSplitAfterN)

	// 以一个或者多个空格分割成切片
	bytesFields := bytes.Fields([]byte(" aaa b bbbcccd  ddd   "))
	fmt.Println(bytesFields)

	// 根据指定方法分割成切片
	bytesFieldsFunc := bytes.FieldsFunc([]byte(" aa$bb,cddd;..dd##"), func(c rune) bool {
		return !unicode.IsLetter(c) && !unicode.IsNumber(c) // 以 不是字符或者数字 进行分割
	})
	fmt.Println(bytesFieldsFunc)

	// 将 s 数组，以指定的字符 sep 连接成一个新的 byte
	bytesJoin := bytes.Join([][]byte{a,b},[]byte(","))
	fmt.Println(string(bytesJoin))

	// 字节片 s 是否以 prefix 开头
	bytesHasPrefix := bytes.HasPrefix(a,[]byte("aa"))
	fmt.Println(bytesHasPrefix)

	// 字节片 s 是否以 suffix 结尾
	bytesHasSuffix := bytes.HasSuffix(a,[]byte("cc"))
	fmt.Println(bytesHasSuffix)

	// 遍历 s ，以指定的方法来处理每个字符
	bytesMap :=	bytes.Map(func(r rune) rune {
		if r >= 'A' && r <= 'Z' {
			return r
		} else {
			return 'a'
		}
	}, []byte("aabbccASDCbbrrDDSS"))
	fmt.Println(string(bytesMap))

	// 返回 count 次 b，相当于复制 b count 次
	bytesRepeat := bytes.Repeat(a,3)
	fmt.Println(string(bytesRepeat))

	// 返回 s 的大写
	bytesToUpper := bytes.ToUpper(a)
	fmt.Println(string(bytesToUpper))

	// 返回 s 的小写
	bytesToLower := bytes.ToLower([]byte("AAFFERRRKKG"))
	fmt.Println(string(bytesToLower))

	// 所有字母都大写 标题格式
	bytesToTitle := bytes.ToTitle([]byte(" assd dsfsd sdf"))
	fmt.Println(string(bytesToTitle))

	// 使用指定的映射表将 s 中的所有字符修改为大写格式返回。
	bytesToUpperSpecial := bytes.ToUpperSpecial(unicode.SpecialCase{},a)
	fmt.Println(string(bytesToUpperSpecial))

	// 使用指定的映射表将 s 中的所有字符修改为小写格式返回
	bytesToLowerSpecial := bytes.ToLowerSpecial(unicode.SpecialCase{},[]byte("DDDkkddIONJ"))
	fmt.Println(string(bytesToLowerSpecial))

	// 使用指定的映射表将 s 中所有字符修改为大写标题格式返回
	bytesToTitleSpecial := bytes.ToTitleSpecial(unicode.SpecialCase{},[]byte(" assd dsfsd sdf"))
	fmt.Println(string(bytesToTitleSpecial))

	// 每次运行的无效UTF-8字节序列由给定切片替换
	bytesToValidUTF8 := bytes.ToValidUTF8([]byte("\xc3\xb1"),[]byte("ff"))
	fmt.Println(string(bytesToValidUTF8))

	// 空格为分隔，所有首字母大写
	bytesTitle := bytes.Title([]byte(" assd dsfsd sdf"))
	fmt.Println(string(bytesTitle))

	// 去除开头结尾所有的 指定字符串中的任意字符
	bytesTrim := bytes.Trim([]byte("  sdfDD DLKF sldfjDDFfff "), " ")
	fmt.Println(string(bytesTrim))

	// 去除开头结尾所有的 空格换行回车缩进
	bytesTrimSpace := bytes.TrimSpace([]byte("  sdfDD DLKF sldfjDDFfff	 "))
	fmt.Println(string(bytesTrimSpace))

	// 去除结尾所有的 指定字符串中的任意字符
	bytesTrimRight := bytes.TrimRight([]byte("sdfDD45 DLKF23 sldf342"), "0123456789")
	fmt.Println(string(bytesTrimRight))

	// 去除开头所有的 指定字符串中的任意字符
	bytesTrimLeft := bytes.TrimLeft([]byte("343sdfDD45 DLKF23 sldf342"), "0123456789")
	fmt.Println(string(bytesTrimLeft))

	// 去掉 s 开头的 prefix
	bytesTrimPrefix := bytes.TrimPrefix([]byte("sdfDD DLKF sldfjDDFfff"),[]byte("sdf"))
	fmt.Println(string(bytesTrimPrefix))

	// 去掉 s 结尾的 suffix
	bytesTrimSuffix := bytes.TrimSuffix([]byte("sdfDD DLKF sldfjDDFfff"),[]byte("fff"))
	fmt.Println(string(bytesTrimSuffix))

	// 以指定方法 去除 首尾 指定的内容
	bytesTrimFunc := bytes.TrimFunc([]byte("sdfDD DLKF sldfjDDFfff"), unicode.IsLetter)
	fmt.Println(string(bytesTrimFunc))

	// 按自定义方法 去除开头所有指定内容
	bytesTrimLeftFunc := bytes.TrimLeftFunc([]byte("sdfDD DLKF sldfjDDFfff"), unicode.IsLetter)
	fmt.Println(string(bytesTrimLeftFunc))

	// 按自定义方法 去除结尾所有指定内容
	bytesTrimRightFunc := bytes.TrimRightFunc([]byte("sdfDD DLKF sldfjDDFfff"), unicode.IsLetter)
	fmt.Println(string(bytesTrimRightFunc))

	// 自定义方法检索首个字符的位置
	bytesIndexFunc := bytes.IndexFunc([]byte("Hello, 你好呀"), func(c rune) bool {
		return unicode.Is(unicode.Han, c) // 是否包含中文字符
	})
	fmt.Println(bytesIndexFunc)

	// 自定义方法检索 最后一个字符在 s 中的位置
	bytesLastIndexFunc := bytes.LastIndexFunc([]byte("sdfDD DLKF sldfjDDFfff"),unicode.IsLetter)
	fmt.Println(bytesLastIndexFunc)

	// byte类型转rune类型
	bytesRunes := bytes.Runes([]byte("sdfDD DLKF sldfjDDFfff"))
	fmt.Println(string(bytesRunes))

	// 替换，将 s 中的 old 替换成 new，n 为替换的个数，-1 为替换所有
	bytesReplace := bytes.Replace([]byte("sdfDD DLKF sldfjDDFfff"),[]byte("D"),[]byte("d"),-1)
	fmt.Println(string(bytesReplace))

	// 将 s 中的 old 替换成 new
	bytesReplaceAll := bytes.ReplaceAll([]byte("sdfDD DLKF sldfjDDFfff"),[]byte("D"),[]byte("d"),)
	fmt.Println(string(bytesReplaceAll))

	// 以 sep 在 s 中的第一个位置进行对 s 进行切割
	bytesCutBefore,bytesCutAfter,bytesCutBool := bytes.Cut([]byte("sdfDD DLKF sldfjDDFfff"),[]byte("DD"))
	fmt.Println(string(bytesCutBefore),string(bytesCutAfter),bytesCutBool)

}

func bytesBufferMain()  {
	// 使用 byte 创建一个 buf
	bytesNewBuffer := bytes.NewBuffer([]byte("aaabbbccc"))

	// 使用 string 创建一个 buf
	bytesNewBufferString := bytes.NewBufferString("aaabbbccc")

	// 将 buf 转切片
	bytesBufferBytes := bytesNewBuffer.Bytes()
	fmt.Println(string(bytesBufferBytes))

	// 将 buf 转 string
	bytesBufferString := bytesNewBufferString.String()
	fmt.Println(bytesBufferString)

	// 返回缓冲区 未读 的字节数
	bytesBufferLen := bytesNewBuffer.Len()
	fmt.Println(bytesBufferLen)

	// 缓冲区的总空间，即分配空间
	bytesBufferCap := bytesNewBuffer.Cap()
	fmt.Println(bytesBufferCap)

	// 丢弃前 n 个未读字节外的其他所有字节
	bytesNewBufferString.Truncate(3)

	// 将缓冲区重置为空
	bytesNewBufferString.Reset()
	// 测试缓冲区是否重置为空
	fmt.Println("测试缓冲区重置为空",bytesNewBufferString.String())

	bytesBufferCapGrowtest := bytesNewBuffer.Cap()
	fmt.Println("测试缓冲区容量增加",bytesBufferCapGrowtest)

	// 增加缓冲的容量，再增加 n + 原分配的长度 个字节
	bytesNewBuffer.Grow(12)
	// 测试缓冲区的容量是否增加
	fmt.Println("测试缓冲区容量增加",bytesNewBuffer.Cap())

	// 将 p 写入缓冲区，返回 p 的长度
	bytesBufferWrite,_ := bytesNewBuffer.Write([]byte("dddeeefff"))
	fmt.Println(bytesBufferWrite)

	// 将 c 写入缓冲区
	bytesNewBuffer.WriteByte(byte('i'))
	bytesNewBuffer.WriteRune('j')

	// 将 s 写入缓冲区，返回 s 的长度
	bytesBUfferWriteString,_ := bytesNewBuffer.WriteString("ggghhh")
	fmt.Println(bytesBUfferWriteString)
	// 测试缓冲区写入的内容
	fmt.Println(bytesNewBuffer.String())

	// 将数据写入 w(io.write) , n 为写入的字节数
	w:= os.Stdout
	bytesBufferWriteTo,_ := bytesNewBuffer.WriteTo(w)
	fmt.Println(bytesBufferWriteTo)

	// 从 io.reader 中读取数据，附加到缓冲区，返回读取的字节数 n
	bytesBufferReadFrom,_ := bytesNewBuffer.ReadFrom(strings.NewReader("hello , world"))
	fmt.Println(bytesBufferReadFrom)
	// 验证缓冲区数据
	fmt.Println(bytesNewBuffer.String())

	// 将缓冲区的内容读取 len(p) 到 p 里面，返回读取的字节数
	bufferByteRead := []byte("             ")
	bytesBufferByte,_ := bytesNewBuffer.Read(bufferByteRead)
	fmt.Println(bytesBufferByte)
	// 验证 p 的数据
	fmt.Println(string(bufferByteRead))

	// 返回缓冲区 n 个字节的切片
	// 向缓冲区写入数据
	bytesNewBuffer.Write([]byte("aaaaaabbbbbbccccccdddddd"))
	bytesBufferNext := bytesNewBuffer.Next(6)
	fmt.Println(string(bytesBufferNext))

	// 读取并返回缓冲区下一个字节
	bytesBufferReadByte,_ := bytesNewBuffer.ReadByte()
	fmt.Println(string(bytesBufferReadByte))

	// 读取并返回缓冲区中下一个UTF-8编码
	bytesBufferReadRuneRune,bytesBufferReadRuneInt,_ := bytesNewBuffer.ReadRune()
	fmt.Println(string(bytesBufferReadRuneRune),bytesBufferReadRuneInt)

	// 最近一次调用ReadRune方法读取的unicode码值。如果最近一次读写操作不是ReadRune，本方法会返回错误
	bytesNewBuffer.UnreadRune()

	// 最近一次读取操作读取的最后一个字节。如果最后一次读取操作之后进行了写入，本方法会返回错误。
	bytesNewBuffer.UnreadByte()

	// 读取到 delim 字节，并返回到 delim 字节的切片
	bytesBufferReadBytes,_ := bytesNewBuffer.ReadBytes('c')
	fmt.Println(string(bytesBufferReadBytes))

	// 读取到 delim 字节，并返回到 delim 字节的字符串
	bytesBufferReadString,_ := bytesNewBuffer.ReadString('d')
	fmt.Println(bytesBufferReadString)
}

func bytesReaderMain()  {
	// 创建一个从 b 读取的数据的 Reader
	bytesReader := bytes.NewReader([]byte("aaaaaabbbbbbccccccdddddd"))

	// 返回 Reader包含的切片 中还没读取的字节数
	bytesReaderLen := bytesReader.Len()
	fmt.Println(bytesReaderLen)

	// 返回 Reader 的原始字节数
	bytesReaderSize := bytesReader.Size()
	fmt.Println(bytesReaderSize)

	// 从 Reader 中读取 n 字节放入 b 中，返回读取的字节数
	bytesRead := []byte("abc")
	bytesReaderRead,_ := bytesReader.Read(bytesRead)
	fmt.Println(string(bytesRead))
	fmt.Println(bytesReaderRead)
	fmt.Println(bytesReader.Len())

	//从 Reader 中读取索引到 off 放入 b 中，返回读取的字节数
	bytesReadAt := []byte("abc")
	bytesReaderReadAt,_ := bytesReader.ReadAt(bytesReadAt,5)
	fmt.Println(string(bytesReadAt))
	fmt.Println(bytesReaderReadAt)
	fmt.Println(bytesReader.Len())

	// 读取一个字节并返回该字节
	bytesReaderReadByte,_ := bytesReader.ReadByte()
	fmt.Println(string(bytesReaderReadByte))

	// 最近一次读取操作读取的最后一个字节。如果最后一次读取操作之后进行了写入，本方法会返回错误。
	bytesReader.UnreadByte()

	// 读取并返回缓冲区中下一个UTF-8编码
	bytesReaderReadRuneRune,bytesReaderReadRuneSize,_ := bytesReader.ReadRune()
	fmt.Println(bytesReaderReadRuneRune,bytesReaderReadRuneSize)

	// 最近一次调用ReadRune方法读取的unicode码值。如果最近一次读写操作不是ReadRune，本方法会返回错误
	bytesReader.UnreadRune()

	// 根据 whence 的值，修改并返回进度下标 i ，当 whence == 0 ，进度下标修改为 off，当 whence == 1 ，
	// 进度下标修改为 i+off，当 whence == 2 ，进度下标修改为 len[s]+off.
	// off 可以为负数，whence 的只能为 0，1，2，当 whence 为其他值或计算后的进度下标越界，则返回错误。
	bytesReaderSeek,_ := bytesReader.Seek(5,6)
	fmt.Println(bytesReaderSeek)

	// 将数据写入 w(io.write) , n 为写入的字节数
	w:= os.Stdout
	bytesReaderWriteTo,_ := bytesReader.WriteTo(w)
	fmt.Println(bytesReaderWriteTo)

	// 重置 Reader
	bytesReader.Reset([]byte("abc"))

}

